// This file is part of Spectrum Editor Called SECS.
//
// Spectrum Editor Called SECS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Spectrum Editor Called SECS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spectrum Editor Called SECS.  If not, see <http://www.gnu.org/licenses/>.

struct Wave {
  std::vector <unsigned char> header;
  std::vector <std::vector <int> > samples;
  int number_of_channels, sample_rate, byte_rate, block_align, bits_per_sample, maximum_amplitude;

  Wave(std::string file_name) {
    FILE* file = fopen(file_name.c_str(), "rb");
    // get header
    unsigned char header_data[44];
    fread(header_data, sizeof(unsigned char), 44, file);
    for (int i = 0; i < 44; i++)
      header.push_back(header_data[i]);
    // parse header
    number_of_channels = data_to_int(std::vector <unsigned char> (header.begin() + 22, header.begin() + 23));
    sample_rate = data_to_int(std::vector <unsigned char> (header.begin() + 24, header.begin() + 27));
    byte_rate = data_to_int(std::vector <unsigned char> (header.begin() + 28, header.begin() + 31));
    block_align = data_to_int(std::vector <unsigned char> (header.begin() + 32, header.begin() + 33));
    bits_per_sample = data_to_int(std::vector <unsigned char> (header.begin() + 34, header.begin() + 35));

    maximum_amplitude = powi(2, bits_per_sample - 1);
    int bytes_per_sample = bits_per_sample / 8;
    int number_of_samples = data_to_int(std::vector <unsigned char> (header.begin() + 40, header.begin() + 43)) / block_align;

    // get samples
    for (int i = 0; i < number_of_samples; i++) {
      std::vector <int> sample;
      for (int j = 0; j < number_of_channels; j++) {
        unsigned char channel_data[bytes_per_sample];
        fread(channel_data, sizeof(unsigned char), bytes_per_sample, file);
        std::vector <unsigned char> channel_vector;
        for (int k = 0; k < bytes_per_sample; k++)
          channel_vector.push_back(channel_data[k]);
        int channel = data_to_int(channel_vector);
        if (channel > maximum_amplitude)
           channel -= maximum_amplitude * 2;
        sample.push_back(channel);
      }
      samples.push_back(sample);
    }
  }

  int powi(int base, int power) {
    if (power == 0) return 1;
    if (power == 1) return base;

    int half = powi(base, power / 2);
    if (power % 2 == 0)
      return half * half;
    else
      return base * half * half;
  }

  int data_to_int(std::vector <unsigned char> data) {
    int integer = 0;
    for (int i = 0; i < data.size(); i ++)
      integer += data[i] * powi(256, i);
    return (int)integer;
  }
};
